home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 6 / develop 6 code / TCP / NewsWatcher / NewsWatcher 2.0d15 source / source / next.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-17  |  6.0 KB  |  238 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     next.c
  4.  
  5.     This module handles the next article, thread, and group commands.
  6.     
  7.     Portions copyright © 1990, Apple Computer.
  8.     Portions copyright © 1993, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include "glob.h"
  13. #include "article.h"
  14. #include "close.h"
  15. #include "mark.h"
  16. #include "next.h"
  17. #include "subject.h"
  18. #include "util.h"
  19.  
  20.  
  21. /*    DoNextArticle is called in response to the menu command of the same
  22.     name.  It closes the current message window, and opens the next
  23.     unread message or group.
  24. */
  25.  
  26. void DoNextArticle (WindowPtr wind, Boolean continueInParent)
  27. {
  28.     WindowPtr parent;
  29.     TWindow **info;
  30.     Cell theCell,newCell;
  31.     ListHandle theList;
  32.     short cellData,cellDataLen,numCells;
  33.     TGroup **groupArray,theGroup;
  34.     TSubject **subjectArray, theSubject;
  35.     EWindowKind kind;
  36.     short index, threadHeadIndex, result;
  37.     Boolean inCollapsedThread;
  38.  
  39.     info = (TWindow**)GetWRefCon(wind);
  40.     kind = (**info).kind;
  41.     theList = (**info).theList;
  42.     
  43.     if (kind == kArticle) {
  44.         continueInParent = true;
  45.     } else if (!continueInParent) {
  46.         SetPt(&theCell, 0, 0);
  47.         if (LGetSelect(true, &theCell, theList)) {
  48.             if (kind == kSubject) {
  49.                 cellDataLen = 2;
  50.                 LGetCell(&cellData, &cellDataLen, theCell, theList);
  51.             }
  52.         } else if (kind == kSubject) {
  53.             continueInParent = true;
  54.         } else {
  55.             SysBeep(1);
  56.             return;
  57.         }
  58.     }
  59.  
  60.     if (continueInParent) {
  61.         index = (kind == kSubject) ? (**info).parentGroup : 
  62.             (**info).parentSubject;
  63.         parent = (**info).parentWindow;
  64.         info = (TWindow**)GetWRefCon(parent);
  65.         kind = (**info).kind;
  66.         theList = (**info).theList;
  67.         subjectArray = (**info).subjectArray;
  68.         numCells = (**theList).dataBounds.bottom;
  69.         threadHeadIndex = (kind == kSubject && (*subjectArray)[index].collapsed) ? 
  70.             (*subjectArray)[index].threadHeadIndex : index;
  71.         if (FindParentCell(parent, threadHeadIndex, &theCell)) {
  72.             if (kind == kSubject) {
  73.                 if ((*subjectArray)[index].collapsed) {
  74.                     cellData = (*subjectArray)[index].nextInThread;
  75.                     inCollapsedThread = cellData != -1;
  76.                 } else {
  77.                     inCollapsedThread = false;
  78.                 }
  79.                 if (!inCollapsedThread) {
  80.                     theCell.v++;
  81.                     if (theCell.v < numCells) {
  82.                         cellDataLen = 2;
  83.                         LGetCell(&cellData, &cellDataLen, theCell, theList);
  84.                     }
  85.                 }
  86.             } else {
  87.                 theCell.v++;
  88.             }
  89.         } else {
  90.             theCell.v = numCells;
  91.         }
  92.         DoCloseWindow(wind);
  93.         BringToFront(parent);
  94.         wind = parent;
  95.         if (theCell.v >= numCells) {
  96.             if (kind == kSubject) {
  97.                 DoNextArticle(wind, true);
  98.             } else {
  99.                 SysBeep(1);
  100.             }
  101.             return;
  102.         }
  103.     }
  104.     
  105.     if (kind == kSubject) {
  106.         subjectArray = (**info).subjectArray;
  107.         numCells = (**theList).dataBounds.bottom;
  108.         newCell = theCell;
  109.         while (true) {
  110.             theSubject = (*subjectArray)[cellData];
  111.             if (!theSubject.read) {
  112.                 SetPt(&theCell, 0, 0);
  113.                 while (LGetSelect(true, &theCell, theList)) 
  114.                     LSetSelect(false, theCell, theList);
  115.                 LSetSelect(true, newCell, theList);
  116.                 LAutoScroll(theList);
  117.                 result = OpenSubjectCell(wind, newCell, 
  118.                     theSubject.collapsed ? theSubject.threadOrdinal : 1);
  119.                 if (result != 1) return;
  120.             };
  121.             if (theSubject.collapsed && theSubject.nextInThread != -1) {
  122.                 cellData = theSubject.nextInThread;
  123.             } else {
  124.                 newCell.v++;
  125.                 if (newCell.v >= numCells) {
  126.                     DoNextArticle(wind, true);
  127.                     return;
  128.                 } else {
  129.                     cellDataLen = 2;
  130.                     LGetCell(&cellData, &cellDataLen, newCell, theList);
  131.                 }
  132.             }
  133.         }
  134.     } else { /* group list */
  135.         groupArray = (**info).groupArray;
  136.         numCells = (**theList).dataBounds.bottom;
  137.         for (newCell = theCell; newCell.v < numCells; newCell.v++) {
  138.             cellDataLen = 2;
  139.             LGetCell(&cellData, &cellDataLen, newCell, theList);
  140.             theGroup = (*groupArray)[cellData];
  141.             if ((kind == kUserGroup && theGroup.unread != nil) ||
  142.                 (kind != kUserGroup && theGroup.lastMess >= theGroup.firstMess)) 
  143.             { 
  144.                 SetPt(&theCell, 0, 0);
  145.                 while (LGetSelect(true, &theCell, theList))
  146.                     LSetSelect(false, theCell, theList);
  147.                 LSetSelect(true, newCell, theList);
  148.                 LAutoScroll(theList);
  149.                 result = OpenGroupCell(wind, newCell);
  150.                 if (result != 1) return;
  151.             }
  152.         }
  153.         SysBeep(1);
  154.     }
  155. }
  156.  
  157.  
  158. /*    DoNextThread is called in response to the menu command of the same
  159.     name. 
  160. */
  161.  
  162. void DoNextThread (WindowPtr wind)
  163. {
  164.     WindowPtr parent;
  165.     TWindow **info, **parentInfo;
  166.     ListHandle theList;
  167.     TSubject **subjectArray;
  168.     Cell theCell;
  169.     short cellData, cellDataLen, threadHeadIndex, index;
  170.     
  171.     info = (TWindow**)GetWRefCon(wind);
  172.     
  173.     switch ((**info).kind) {
  174.         case kUserGroup:
  175.         case kFullGroup:
  176.         case kNewGroup:
  177.             DoNextArticle(wind, false);
  178.             break;
  179.         case kSubject:
  180.             theList = (**info).theList;
  181.             subjectArray = (**info).subjectArray;
  182.             SetPt(&theCell, 0, 0);
  183.             if (LGetSelect(true, &theCell, theList)) {
  184.                 cellDataLen = 2;
  185.                 LGetCell(&cellData, &cellDataLen, theCell, theList);
  186.                 threadHeadIndex = (*subjectArray)[cellData].threadHeadIndex;
  187.                 if (threadHeadIndex != cellData) 
  188.                     MarkThread(wind, threadHeadIndex, true);
  189.                 DoNextArticle(wind, false);
  190.             } else {
  191.                 SysBeep(1);
  192.             }
  193.             break;
  194.         case kArticle:
  195.             parent = (**info).parentWindow;
  196.             index = (**info).parentSubject;
  197.             parentInfo = (TWindow**)GetWRefCon(parent);
  198.             subjectArray = (**parentInfo).subjectArray;
  199.             threadHeadIndex = (*subjectArray)[index].threadHeadIndex;
  200.             MarkThread(parent, threadHeadIndex, true);
  201.             DoNextArticle(wind, true);
  202.             break;
  203.     }
  204. }
  205.  
  206.  
  207. /*    DoNextGroup is called in response to the menu command of the same
  208.     name.  If a subject window is open, it marks all of the subjects
  209.     read, closes the subject window, and then does a Next Message.
  210.     If a user group window is open, it just does a Next Message.
  211. */
  212.  
  213. void DoNextGroup (WindowPtr wind)
  214. {
  215.     TWindow **info;
  216.     WindowPtr parentWind;
  217.     
  218.     info = (TWindow**) GetWRefCon(wind);
  219.     
  220.     switch ((**info).kind) {
  221.         case kUserGroup:
  222.         case kFullGroup:
  223.         case kNewGroup:
  224.             DoNextArticle(wind, false);
  225.             break;
  226.         case kSubject:
  227.             MarkAllSubjects(wind, true);
  228.             DoNextArticle(wind, true);
  229.             break;
  230.         case kArticle:
  231.             parentWind = (**info).parentWindow;
  232.             DoCloseWindow(wind);
  233.             BringToFront(parentWind);
  234.             DoNextGroup(parentWind);
  235.             break;
  236.     }
  237. }
  238.